using System;
using System.Threading;
using SistemaLib.sipe.lib;

namespace SistemaLib.sipe.db.sqlserver
{
	/// <summary>
	/// Summary description for DbBase.
	/// </summary>
	public class DbBase
	{

		// Atributos
		protected DbConnection mConn;
		protected BusinessException mErrores;

		// Propiedades de acceso
		protected DbConnection DbConnection 
		{
			get 
			{
				if ( DbBase.EstadoTransaccional )
					return DbBase.ThreadDbConnection;
				else
					return mConn;
			}
			set 
			{
				mConn = value;
			}
		}

		public DbBase()
		{
			this.DbConnection = new DbConnection();
		}

		private static int Contador
		{
			get
			{
				if ( Thread.GetNamedDataSlot("contador") == null )
					return 0;
				LocalDataStoreSlot myTLSValue = Thread.GetNamedDataSlot("contador");
				if ( myTLSValue == null )
					return 0;
				if ( Thread.GetData(myTLSValue) == null )
					return 0;

				return (int)Thread.GetData(myTLSValue);
			}
			set
			{
				if ( Thread.GetNamedDataSlot("contador") == null )
					Thread.AllocateNamedDataSlot("contador");
				LocalDataStoreSlot myData = Thread.GetNamedDataSlot("contador");
				Thread.SetData(myData, value);
			}
		}

		protected static bool EstadoTransaccional
		{
			get 
			{
				LocalDataStoreSlot myTLSValue;              
				myTLSValue = Thread.GetNamedDataSlot("conn");
				if ( myTLSValue == null )
					return false;
				return (Thread.GetData(myTLSValue)!=null);
			}
		}

		protected static DbConnection ThreadDbConnection
		{
			get
			{
				LocalDataStoreSlot myTLSValue;              
				myTLSValue = Thread.GetNamedDataSlot("conn");
				DbConnection conn = (DbConnection)Thread.GetData(myTLSValue);
				return conn;
			}
		}

		public static void BeginTransaction()
		{
			Contador++;

			if ( Thread.GetNamedDataSlot("conn") == null )
				Thread.AllocateNamedDataSlot("conn");
			
			if ( EstadoTransaccional )
				return;
			
			LocalDataStoreSlot myData;
			myData = Thread.GetNamedDataSlot("conn");
            OpenConnection(false);
            DbConnection conn = (DbConnection)Thread.GetData(myData);
			conn.BeginTransaction();
			Thread.SetData(myData, conn);
		}

		public static void CommitTransaction()
		{
			if ( ! EstadoTransaccional )
				throw new Exception( "No se puede Commitear una transaccion que no Existe");

			LocalDataStoreSlot myTLSValue;              
			myTLSValue = Thread.GetNamedDataSlot("conn");
			DbConnection conn = (DbConnection)Thread.GetData(myTLSValue);
			conn.CommitTransaction();
		}

		public static void RollbackTransaction()
		{
			if ( ! EstadoTransaccional )
				throw new Exception( "No se puede Rollbackear una transaccion que no Existe");

			LocalDataStoreSlot myTLSValue;              
			myTLSValue = Thread.GetNamedDataSlot("conn");
			DbConnection conn = (DbConnection)Thread.GetData(myTLSValue);
			if ( conn.isTransaction )
				conn.RollbackTransaction();
		}

		public static void CloseConnection()
		{
			Contador--;
			if ( Contador > 0 )
				return;

			LocalDataStoreSlot myTLSValue;              
			myTLSValue = Thread.GetNamedDataSlot("conn");
			DbConnection conn = (DbConnection)Thread.GetData(myTLSValue);
            conn.NoCerrar = false;
            conn.Close();
			Thread.FreeNamedDataSlot("conn");
		}

        public static void OpenConnection( bool noCerrar)
        {
            if (Thread.GetNamedDataSlot("conn") == null)
                Thread.AllocateNamedDataSlot("conn");

            LocalDataStoreSlot myTLSValue;
            myTLSValue = Thread.GetNamedDataSlot("conn");
            if (Thread.GetData(myTLSValue) == null)
            {
                DbConnection conn = new DbConnection();
                conn.Open(noCerrar);
                Thread.SetData(myTLSValue, conn);
            }
            else
            {
                DbConnection conn = (DbConnection)Thread.GetData(myTLSValue);
                if (!conn.IsOpen)
                    conn.Open(noCerrar);
            }

        }

	}
}
